XMLDSig and XAdES Signatures

Description

This file contains several use examples of the TRIDENT document signature API for generating XMLDSig and XAdES signatures. In all cases, signatures are performed on the Web resources corresponding to the signature processes, and server signing identities are used. As a result, all the signatures are generated in the following four steps:

  1. Obtaining the token for accessing the signature operations

  2. Creating the document signature process

  3. Executing the document signature process

  4. Obtaining the signed document

Steps 1, 3, and 4 are not particular to generating XMLDSig or XAdES signatures. These steps are essentially performed in the same way as explained in the example of signing a PDF document. Thus, in all the examples, we look exclusively at step 2 and, specifically, on the value of the parameters property, which the signature definition must have in each case.

XML Signature on Any Type of Data

This section illustrates how to sign an arbitrary document type, e.g., a JPG file with an image. To obtain an external signature separate from the file, i.e., an externally detached XML signature, we can request the creation of the corresponding signature process with the following message:

POST /trustedx-resources/esignsp/v2/signer_processes HTTP/1.1
Authorization: Bearer 633c14e7f7f3534dc785713a243c5a7b46285bdd5a67e65142e3752413b6450a
Host: txeidas.safelayer.com:443
Content-Type: multipart/form-data; boundary=docsignb6b7d157e6de164b
--docsignb6b7d157e6de164b
Content-Disposition: form-data; name="process"
Content-Type: application/json
{
"process_type" : "urn:safelayer:eidas:processes:document:sign:esigp",
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xmldsig",
"signature_target" : {
"signature_packaging" : "detached"
}
}
},
"labels": [["sign"]],
"ui_locales" : ["en_US"],
"finish_callback_url" : "https://docsign.safelayer.com/xmlsignatures/callback"
}
--docsignb6b7d157e6de164b
Content-Disposition: form-data; name="document";
Content-Type: image/png
Content-Transfer-Encoding: binary
<image>
--docsignb6b7d157e6de164b--

The JSON representation of the signature definition contained in the previous messages is:

{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xmldsig",
"signature_target" : {
"signature_packaging" : "detached"
}
}
}
}

Note that the signature defined has the following characteristics:

  • It is an XML signature (""signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml")

  • The signature format is XMLDSig ("type" : "xmldsig")

  • The signature is separate from the data ("signature_packaging" : "detached").

Because the signature is a separate from the data, any process for verifying it will have to obtain the data it refers to. If we want the signature to include information on how to recover this data, we can extend the signature as follows:

{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xmldsig",
"signature_target" : {
"signature_packaging" : "detached",
"nodes_to_sign" : [ {
"type" : "raw_reference",
"uri" : "https://docsign.safelayer.com/documents/image.jpg"
} ]
}
}
}
}

As you can see, the signed document has the URI "https://docsign.safelayer.com/documents/image.jpg".

Lastly, if we want the signature defined to have the interoperability and acceptance of an advanced electronic signature format, we can assign the "xades-bes" value to the "parameters.type" element of the signature definition, which gives us the following definition:

{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xades-bes",
"signature_target" : {
"signature_packaging" : "detached",
"nodes_to_sign" : [ {
"type" : "raw_reference",
"uri" : "https://docsign.safelayer.com/documents/image.jpg"
} ]
}
}
}
}

XAdES Signature on an XML Document

This section describes how to sign an XML document that contains information on a contract. As you would expect with this type of document, we want the signature to be in the contract. Furthermore, given the nature of the document signed, we want the signature to have the same legal validity as a handwritten signature and that its validity is guaranteed regardless of who validates it. For these reasons, we use an enveloped XML signature with the XAdES-EPES format for which we include the following signature definition in the message for creating the signature process:

{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xades-epes",
"signature_target" : {
"signature_packaging" : "enveloped"
},
"policy_identifier" : {
"policy_id" : {
"identifier" : {
"uri": "urn:oid:2.16.724.1.3.1.1.2.1.9",
"qualifier" : "OIDAsURN"
},
"description" : "Política de firma electrónica para la Administración General del Estado"
},
"policy_hash" : {
"digest_algorithm_identifier" : {"id" : "sha1"},
"digest_value" : "G7roucf600+f03r/o0bAOQ6WAs0="
},
"policy_qualifiers" : [
{
"type" : "spuri",
"uri" : "https://sede.060.gob.es/politica_de_firma_anexo_1.pdf"
 
}
]
}
}
}
}

As you can see, the signature created by the signature definition has the following characteristics:

  • It is an XML signature ("signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml")

  • The signature is in the signed document ("signature_packaging" : "enveloped").

  • The signature format is XAdES-EPES ("type" : "xades-epes").

  • The policy for generating (and validating) the signature is "Política de firma electrónica para la Administración General del Estado", which is identified with the OID 2.16.724.1.3.1.1.2.1.9 and described (in Spanish) in the document at https://sede.060.gob.es/politica_de_firma_anexo_1.pdf

To specify the exact location where the signature is inserted in the signed document and the canonicalization algorithm used for obtaining the signature, we include the signature_placement and default_c14n_method elements in the signature definition. In addition, if you expect that the document will be signed in the future (by other signers, countersignatures), you must include the "enveloped_transform" element with the "multiple_signatures" value.

{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xades-epes",
"signature_target" : {
"signature_packaging" : "enveloped",
"enveloped_transform": "multiple_signatures",
"nodes_to_sign" : [
{
"type" : "document_reference",
"xpath" : "/",
"uri_type" : "xpointer_xpath"
}
],
"signature_placement" : {
"type" : "first_child_of",
"xpath" : "/"
}
},
"default_c14n_method" : "c14nWithComments",
"policy_identifier" : {
"policy_id" : {
"identifier" : {
"uri": "urn:oid:2.16.724.1.3.1.1.2.1.9",
"qualifier" : "OIDAsURN"
},
"description" : "Política de firma electrónica para la Administración General del Estado"
},
"policy_hash" : {
"digest_algorithm_identifier" : {"id" : "sha1"},
"digest_value" : "G7roucf600+f03r/o0bAOQ6WAs0="
},
"policy_qualifiers" : [
{
"type" : "spuri",
"uri" : "https://sede.060.gob.es/politica_de_firma_anexo_1.pdf"
 
}
]
}
}
}
}

As you can see, the signature is to be the first child node of the signed document ("signature_placement.type" : "first_child_of", "signature_placement.xpath" : "/") and the calculation of the digital signature will be performed on the canonical form of the contract obtained with the http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments algorithm, which preserves the comments contained in the XML document corresponding to the contract ("default_c14n_method" : "c14nWithComments").

Data and XML Signature Container

Let's now see what the signature definition included in the creation message for the signature process must look like so that the signature generated by this process is contained in the same XML document and at the same level as the signed data. I.e., so that we have an internally detached XML signature. Imagine we want to perform an XAdES-BES signature on the <data> element of an XML document whose root element is <record>, for which the path of this element is /record/data and for which we want the signature to be inserted straight after and at the same level as this element. The following signature definition will do just this:

{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xades-bes",
"signature_target" : {
"signature_packaging" : "detached",
"nodes_to_sign" : [ {
"type" : "document_reference",
"xpath" : "/record/data"
} ],
"signature_placement" : {
"type" : "after",
"xpath" : "/record/data"
}
}
}
}
}

As you can see, the signature has the following characteristics:

  • It is an XML signature ("signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml")

  • The signature format is XAdES-BES ("type" : "xades-bes")

  • The signature is separate from the data ("signature_packaging" : "detached").

  • The signature is in the same XML document as the signed data and at the same level ("signature_placement.type" : "after", "signature_placement.xpath" : "/record/data").

Lastly, by repeating the signature creation process for n different signers, we can incorporate n signatures generated on the document's data in the XML document. Thus, we will have generated an XML structure that contains both certain data and n parallel signatures that requires a certain workflow for this data.

Adding an Enveloped Countersignature to a Document That Contains One or More XAdES Signatures

If you have a document with a single XAdES signature and you want to add an enveloped countersignature to it, you can use the following signature definition:


{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xades-bes",
"signature_target" : {
"type" : "signature",
"signature_packaging" : "enveloped"
}
}
}
}


Note

If the document has only one signature, the signature has only been countersigned once, and you want to countersign this countersignature, you can also use the above signature definition.

Likewise, if you have a document with a single signature and you want to obtain a detached countersignature of it, you can use the following signature definition:

{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xades-bes",
"signature_target" : {
"type" : "signature",
"signature_packaging" : "detached"
}
}
}
}

If you have a document with two signatures and you want to countersign the first one (with an enveloped countersignature), you can use the following signature definition:

{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xades-bes",
"signature_target" : {
"type" : "signature",
"signature_packaging" : "enveloped"
"nodes_to_sign" : [{
"type" : "signature_reference",
"xpath" : "//ds:Signature[1]"
} ],
}
}
}
}

Lastly, if you have a document with multiple signatures and you want to add a detached countersignature to it, you must specify which signatures must be countersigned and where the countersignature must be placed:

{
"signer" : {
"signature_policy_id" : "urn:safelayer:eidas:policies:sign:document:xml",
"parameters": {
"type" : "xades-bes",
"signature_target" : {
"type" : "signature",
"signature_packaging" : "detached"
"nodes_to_sign" : [
{
"type" : "signature_reference",
"xpath" : "//*[@Id='signature1']"
},
{
"type" : "signature_reference",
"xpath" : "//*[@Id='signature2']"
}
],
"signature_placement" : {
"type" : "after",
"xpath" : "/record/data"
}
}
}
}
}